package com.ehotting.edsta.circuitDesign.gen.element.helper;

import com.ehotting.edsta.circuitDesign.domain.EsCircuitCodeDataTemplate;
import com.ehotting.edsta.circuitDesign.domain.EsSceneParam;
import com.ehotting.edsta.circuitDesign.gen.ScriptConstants;
import com.ehotting.edsta.circuitDesign.gen.ScriptLogger;
import com.ehotting.eaf.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class ElementScriptHelper {

    /**
     * 针对输出参数，定义参数的数组
     * 比如：R1定义数组为R1List
     * @param outputParamList
     * @return
     */
    private  String defineGlobalVariable( List<EsSceneParam> outputParamList){
        StringBuffer buf = new StringBuffer();
        for(EsSceneParam esSceneParam : outputParamList){
            buf.append(esSceneParam.getCode()+"List = new java.util.ArrayList();");
            buf.append(ScriptConstants.LINE);

            buf.append(ScriptConstants.LINE);
        }
        buf.append("allList = new java.util.ArrayList();");
        buf.append(ScriptConstants.LINE);
        return buf.toString();
    }

    /***
     * 初始化参数数组
     * @param outputParamList
     * @return
     */
    private  String initGlobalVariable( List<EsSceneParam> outputParamList){
        StringBuffer buf = new StringBuffer();
        buf.append("def init(){");
        buf.append(ScriptConstants.LINE);
        for(int i = 0;i<outputParamList.size();i++){
            EsSceneParam esSceneParam = outputParamList.get(i);
            buf.append(ScriptConstants.TAB);
//            buf.append(esSceneParam.getCode()+"List.addAll(ElementDataHelper.findByCode(\""+esSceneParam.getCode()+"\"));");
            buf.append(esSceneParam.getCode()+"List.addAll(ElementDataHelper.findByType("+esSceneParam.getComponentType()+"));");
            buf.append(ScriptConstants.LINE);
            buf.append("System.out.println("+esSceneParam.getCode()+"List.size());");
        }
        buf.append(ScriptConstants.TAB);
        buf.append("allList.addAll(ElementDataHelper.findAll());");
        buf.append(ScriptConstants.LINE);
        buf.append("}");
        buf.append(ScriptConstants.LINE);
        buf.append("init();");
        buf.append(ScriptConstants.LINE);
        return buf.toString();
    }

    public  String genHeader(List<EsSceneParam> outputParamList){
        StringBuffer buf = new StringBuffer();
        buf.append(ScriptConstants.defineImport());
        buf.append(ScriptConstants.LINE);
        buf.append(this.defineGlobalVariable(outputParamList));
        buf.append(ScriptConstants.LINE);
        buf.append(this.initGlobalVariable(outputParamList));
        buf.append(ScriptConstants.LINE);
        return buf.toString();
    }


    public String gen(Long circuitId, String functionBody, String callBody,List<EsCircuitCodeDataTemplate> inputParamList, List<EsSceneParam> outputParamList){

        StringBuffer buf = new StringBuffer();

        buf.append(genHeader(outputParamList));
        buf.append(functionBody);
        buf.append(ScriptConstants.LINE);
        buf.append("def ").append(genMainName(circuitId)).append("(");
        for (EsCircuitCodeDataTemplate esSceneParam : inputParamList){
            buf.append(esSceneParam.getCode() + ",");
        }
        buf.append( "outMapList,all){");
        buf.append(ScriptConstants.LINE);
        buf.append(callBody);
        buf.append(ScriptConstants.LINE);
        buf.append("};");
        String script = buf.toString();
        ScriptLogger.info(script);
        return script;
    }


    /***
     * 从表达式中查找含有code.的字符串
     * 比如表达式为：r1.aa +r2.bb / r1.bb,将从中提取出r1.aa,r2.bb,r3，code为r1,返回为r1.aa,r1.bb
     * @param expression
     * @param code
     * @return
     */
    public static Set<String> filterByCode(String expression, String code){
        String[] fields=  filter2Array(expression);
        Set<String> codeList = new HashSet<>();
        for(String field : fields){
            if(StringUtils.hasText(field))
                if(field.trim().indexOf(code+".")>=0){
                    codeList.add(field.trim());
                }
        }
        return codeList;
    }

    /**表达式转换，点转换为下划线，
     * 比如：r1.aa-r2.bb-5转为r1_aa-r2_b-5**/
    public static String replaceNodeToUnderline(String expression){

//        Set<String> fieldSet = filterArgument(expression);
//        for(String field : fieldSet){
//            expression = expression.replaceAll(field,field.replaceAll("\\.","_"));
//        }
        return expression;
    }


    public static Set<String> filterArgument(String content){
        String[] fields=  filter2Array( content);
        Set<String> codeList = new HashSet<>();
        for(String field : fields){
            if(StringUtils.hasText(field) )
                if(isContainsCharacter(field.trim())){
                    codeList.add(field.trim());
                }
        }
        return codeList;
    }


    /**
     * 从表达式中提取带有属性值的变量,并且返回数组
     * 比如：r1.aa +r2.bb / r3,将从中提取出r1.aa,r2.bb
     * @param expression
     * @return
     */
    public static Set<String> filter4Prop(String expression){
        String[] fields=  filter2Array(expression);
        Set<String> codeList = new HashSet<>();
        for(String field : fields){
            if(StringUtils.hasText(field) && field.indexOf(".")!=-1 )
                if(isContainsCharacter(field.trim())){
                    codeList.add(field.trim());
                }
        }
        return codeList;
    }


    /**
     * 从表达式中提取变量,并且返回数组
     * 比如：r1.aa +r2.bb / r3,将从中提取出r1.aa,r2.bb,r3
     * @param expression
     * @return
     */
    public static String[] filter2Array(String expression){
        String regEx="[\\u00A0\\s\"`~!@#$%^&*()+=|{}':;',\\[\\]<>/?~！@#￥%……&*()——+|{}【】‘；：”“'。，、？]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(expression);
        String str = m.replaceAll(" ").trim();
        String[] aa  = str.split(" ");
        return aa;
    }


    /**
     * 判断字符串是否包含字母
     * @param str
     * @return
     */
    public static boolean isContainsCharacter(String str) {
        String regex=".*[a-zA-Z]+.*";
        Matcher m = Pattern.compile(regex).matcher(str);
        return m.matches();
    }


    public static boolean isContainsOperator(String str) {
        String regex=".*[\\+\\-\\*\\/]+.*";
        Matcher m = Pattern.compile(regex).matcher(str);
        return m.matches();
    }


    public String genMethodNameAndArgument(String methodName,List<EsCircuitCodeDataTemplate> inputParamList){
        StringBuffer buf = new StringBuffer();
        buf.append(methodName).append("(");
        for (EsCircuitCodeDataTemplate inputParam : inputParamList){
            buf.append(inputParam.getCode()).append(",");
        }
        buf.append("outMapList,all");
        buf.append( ")");

        return buf.toString();
    }

    public String genMainName(Long circuitId){
        return "main_element_"+circuitId;
    }


    public static void main(String[] args) {
      System.out.println(isContainsOperator("11.2"));
        System.out.println(isContainsOperator("11.2+"));
        System.out.println(isContainsOperator("11.2-"));
        System.out.println(isContainsOperator("11.2*"));
        System.out.println(isContainsOperator("11.2/"));
    }


}